From af6c3017fb0010dcba884da9bef686a92ae7215f Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 26 Oct 2020 13:21:28 -0400 Subject: [PATCH] popovermenu: Allow adding custom items in ui files Support to fill custom child slots in both GtkPopoverMenus and GtkPopoverMenuBars that are created in ui files. --- gtk/gtkpopovermenu.c | 35 +++++++++++++++++++++++++++++++++-- gtk/gtkpopovermenubar.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c index 4c33b0011d..751d14c176 100644 --- a/gtk/gtkpopovermenu.c +++ b/gtk/gtkpopovermenu.c @@ -35,6 +35,7 @@ #include "gtkpopovermenubar.h" #include "gtkshortcutmanager.h" #include "gtkshortcutcontroller.h" +#include "gtkbuildable.h" /** @@ -99,7 +100,8 @@ * Possible values include "action-disabled", "action-missing", "macos-menubar". * This is mainly useful for exported menus, see gtk_application_set_menubar(). * - "custom": a string used to match against the ID of a custom child added - * with gtk_popover_menu_add_child() or gtk_popover_menu_bar_add_child(). + * with gtk_popover_menu_add_child(), gtk_popover_menu_bar_add_child(), or + * in the ui file with ``. * * The following attributes are used when constructing sections: * - "label": a user-visible string to use as section heading @@ -155,7 +157,11 @@ enum { PROP_MENU_MODEL }; -G_DEFINE_TYPE (GtkPopoverMenu, gtk_popover_menu, GTK_TYPE_POPOVER) +static void gtk_popover_menu_buildable_iface_init (GtkBuildableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkPopoverMenu, gtk_popover_menu, GTK_TYPE_POPOVER, + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, + gtk_popover_menu_buildable_iface_init)) GtkWidget * gtk_popover_menu_get_parent_menu (GtkPopoverMenu *menu) @@ -568,6 +574,31 @@ gtk_popover_menu_class_init (GtkPopoverMenuClass *klass) gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_MENU); } +static GtkBuildableIface *parent_buildable_iface; + +static void +gtk_popover_menu_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const char *type) +{ + if (GTK_IS_WIDGET (child)) + { + if (!gtk_popover_menu_add_child (GTK_POPOVER_MENU (buildable), GTK_WIDGET (child), type)) + g_warning ("No such custom attribute: %s", type); + } + else + parent_buildable_iface->add_child (buildable, builder, child, type); +} + +static void +gtk_popover_menu_buildable_iface_init (GtkBuildableIface *iface) +{ + parent_buildable_iface = g_type_interface_peek_parent (iface); + + iface->add_child = gtk_popover_menu_buildable_add_child; +} + /** * gtk_popover_menu_new: * diff --git a/gtk/gtkpopovermenubar.c b/gtk/gtkpopovermenubar.c index 0d5658c224..8e7f2a22d0 100644 --- a/gtk/gtkpopovermenubar.c +++ b/gtk/gtkpopovermenubar.c @@ -73,6 +73,7 @@ #include "gtkwidgetprivate.h" #include "gtkmain.h" #include "gtknative.h" +#include "gtkbuildable.h" #define GTK_TYPE_POPOVER_MENU_BAR_ITEM (gtk_popover_menu_bar_item_get_type ()) #define GTK_POPOVER_MENU_BAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_POPOVER_MENU_BAR_ITEM, GtkPopoverMenuBarItem)) @@ -384,7 +385,11 @@ enum static GParamSpec * bar_props[LAST_PROP]; -G_DEFINE_TYPE (GtkPopoverMenuBar, gtk_popover_menu_bar, GTK_TYPE_WIDGET) +static void gtk_popover_menu_bar_buildable_iface_init (GtkBuildableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkPopoverMenuBar, gtk_popover_menu_bar, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, + gtk_popover_menu_bar_buildable_iface_init)) static void tracker_remove (int position, @@ -650,6 +655,31 @@ gtk_popover_menu_bar_init (GtkPopoverMenuBar *bar) gtk_widget_add_controller (GTK_WIDGET (bar), controller); } +static GtkBuildableIface *parent_buildable_iface; + +static void +gtk_popover_menu_bar_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const char *type) +{ + if (GTK_IS_WIDGET (child)) + { + if (!gtk_popover_menu_bar_add_child (GTK_POPOVER_MENU_BAR (buildable), GTK_WIDGET (child), type)) + g_warning ("No such custom attribute: %s", type); + } + else + parent_buildable_iface->add_child (buildable, builder, child, type); +} + +static void +gtk_popover_menu_bar_buildable_iface_init (GtkBuildableIface *iface) +{ + parent_buildable_iface = g_type_interface_peek_parent (iface); + + iface->add_child = gtk_popover_menu_bar_buildable_add_child; +} + /** * gtk_popover_menu_bar_new_from_model: * @model: (allow-none): a #GMenuModel, or %NULL -- 2.30.2